<template>
  <a-modal v-model:open="open" title="新增对齐类目" :width="900" @ok="handleOk">
    <div grid grid-cols-2 gap-4>
      <div overflow-hidden>
        <a-spin :spinning="loading">
          <a-form>
            <a-form-item label="选择站点">
              <a-select
                allow-clear
                v-model:value="website"
                :options="websites"
                label-in-value
                placeholder="请选择"
                :field-names="{
                  label: 'websiteName',
                  value: 'websiteCode',
                }"
                @change="changeWebsite"
              ></a-select>
            </a-form-item>
            <a-form-item label="搜索类目">
              <a-input placeholder="请输入" v-model:value="kw"></a-input>
            </a-form-item>
          </a-form>
        </a-spin>

        <a-table
          row-key="categoryCode"
          :columns="columns"
          :data-source="list"
          size="small"
          :loading="categoryLoading"
          :row-selection="{
            selectedRowKeys: select.keys,
            onChange: changeSelect,
          }"
        >
          <template #bodyCell="{ record, column }">
            <div
              v-if="column.dataIndex == 'navBreadcrumb'"
              truncate
              :title="`[${record.categoryCode}]${record.navBreadcrumb}`"
            >
              [{{ record.categoryCode }}]{{ record.navBreadcrumb }}
            </div>
          </template>
        </a-table>
      </div>

      <div max-h-641px overflow-y-auto overflow-x-hidden>
        <div flex justify-between>
          <div>已选类目</div>
          <a-button type="link" @click="clearAll">清空</a-button>
        </div>

        <div
          flex
          justify-between
          items-center
          v-for="item in select.rows"
          h-8
          class="group"
          :title="item.navBreadcrumb"
        >
          <div truncate px-2>
            [{{ item.categoryCode }}]{{ item.navBreadcrumb }}
          </div>
          <a-button
            :icon="h(DeleteOutlined)"
            type="link"
            hidden
            class="group-hover:inline-block"
            @click="remove(item)"
            flex-shrink-0
          ></a-button>
        </div>
      </div>
    </div>
  </a-modal>
</template>

<script lang="ts" setup>
import { fetchCategoryByWebsiteCode, fetchWebsiteList } from '@/api/website';
import { SiteConfig } from '@/store/config';
import { Category } from '@/types/category';
import { WebSiteWithCategory } from '@/types/website';
import { DeleteOutlined } from '@ant-design/icons-vue';

type W = {
  value: string;
  label: string;
  option: SiteConfig;
};

const props = defineProps<{
  webs: WebSiteWithCategory[];
}>();

const { webs } = toRefs(props);
const webSet = computed(() => {
  const set: Set<string> = new Set();
  for (const item of webs.value) {
    const { website_code, category_code } = item;
    set.add(website_code + category_code);
  }
  return set;
});
const categoryMap = ref<Map<string, Category[]>>(new Map());

const open = ref(false);

const columns = [
  {
    title: '类目名称',
    dataIndex: 'navBreadcrumb',
    ellipsis: true,
  },
];

let callback: (website: SiteConfig, categories: Category[]) => void;
const data = ref<Category[]>([]);
const websites = ref<SiteConfig[]>([]);
const loading = ref(false);
const website = ref<W>();
const kw = ref('');

const init = () => {
  websites.value = [];
  data.value = [];
  categoryMap.value = new Map();
  website.value = undefined;
  select.keys = [];
  select.rows = [];
  kw.value = '';
};

const add = async (cb: typeof callback) => {
  init();
  callback = cb;
  open.value = true;
  loading.value = true;
  const res = await fetchWebsiteList();
  loading.value = false;
  useRes(res, () => {
    websites.value = res.data;
  });
};

const categoryLoading = ref(false);

const changeWebsite = async () => {
  clearAll();
  if (website.value) {
    const { value } = website.value;
    if (!categoryMap.value.has(value)) {
      categoryLoading.value = true;
      const res = await fetchCategoryByWebsiteCode({
        websiteCode: value,
        hasSplits: true,
        removeOrigin: true,
      });
      categoryLoading.value = false;
      useRes(res, () => {
        categoryMap.value.set(value, res.data.categoryList || []);
      });
    }
    data.value = categoryMap.value.get(value)!;
  }
};

const select = reactive({
  keys: [],
  rows: [] as Category[],
});

const list = computed(() => {
  if (website.value) {
    const websiteCode = website.value.value;
    return data.value.filter(item => {
      const { categoryCode, navBreadcrumb, available } = item;
      const has = webSet.value.has(websiteCode + categoryCode);
      if (kw.value) {
        return (
          navBreadcrumb.toLowerCase().includes(kw.value.toLowerCase()) &&
          !has &&
          available
        );
      } else {
        return !has && available;
      }
    });
  } else {
    return [];
  }
});

const changeSelect = (_keys, _rows) => {
  select.keys = _keys;
  select.rows = _rows;
};

const remove = item => {
  select.rows = select.rows.filter(r => r != item);
  select.keys = select.keys.filter(r => r != item.categoryCode);
};

const handleOk = () => {
  callback(website.value!.option, select.rows);
  open.value = false;
};

const clearAll = () => {
  select.keys = [];
  select.rows = [];
};

defineExpose({
  add,
});
</script>
